package bll

import (
	"context"
	"fmt"

	"manager/event"
	"manager/model"
	"manager/model/entity"
	"manager/store"
	"manager/store/postgres"
	"time"

	"manager/auth"
)

type lose struct {
	iLose store.ILose
}

var Lose = &lose{
	iLose: postgres.Lose,
}

func (a *lose) init() func() {
	return func() {}
}

func (a *lose) onEvent(*event.Data) {}

// Create 创建
func (a *lose) Create(ctx context.Context, in *model.LoseCreateRequest) error {
	var (
		err error
	)

	// 获取用户Id
	in.UserId, _ = auth.ContextUserID(ctx)

	// 车辆校验
	if !UserEbike.IsUserBindBike(in.UserId, in.EbikeId) {
		return fmt.Errorf("bike not bind user")
	}

	// 获取车辆名称
	info, err := Ebike.BikeInfo(ctx, in.EbikeId)
	if err != nil {
		return err
	}

	// 图片名称
	if info != nil {
		in.EbikeName = info.Name
		in.EbikeImage = info.Photo
	}

	// 获取车辆电池信息
	_, list, _ := postgres.Battery.List(ctx, &model.BatteryListRequest{
		Index: 1,
		Size:  1,
		Id:    info.BatteryId,
	})

	if len(list) > 0 {
		in.BatteryNo = list[0].BatteryCode
	}

	in.EbikeTypeId = info.TypeID

	// 构建创建现场数据
	c := buildLose(in)
	_, err = a.iLose.Create(ctx, c)
	return err
}

// Update 更新
func (a *lose) Update(ctx context.Context, in *model.LoseUpdateRequest) error {
	var (
		dict = make(map[string]interface{})
	)

	updateAt := time.Now().Unix()
	in.UpdatedAt = &updateAt

	if in.EbikeId != nil {
		dict["ebike_id"] = in.EbikeId
	}

	if in.UserId != nil {
		dict["user_id"] = in.UserId
	}

	if in.Addr != nil {
		dict["addr"] = in.Addr
	}

	if in.LoseTime != nil {
		dict["lose_time"] = in.LoseTime
	}

	if in.Status != nil {
		dict["status"] = in.Status
	}

	if in.LockStatus != nil {
		dict["lock_status"] = in.LockStatus
	}

	if in.Result != nil {
		dict["result"] = in.Result
	}

	if in.SolverId != nil {
		dict["solver_id"] = in.SolverId
	}

	if in.Desc != nil {
		dict["desc"] = in.Desc
	}

	if in.UpdatedAt != nil {
		dict["updated_at"] = in.UpdatedAt
	}

	// do other update here

	return a.iLose.Update(ctx, in.Id, dict)
}

// Delete 删除
func (a *lose) Delete(ctx context.Context, in *model.LoseDeleteRequest) error {
	return a.iLose.Delete(ctx, in.Id)
}

// List 列表查询
func (a *lose) List(ctx context.Context, in *model.LoseListRequest) (*model.LoseListResponse, error) {
	var (
		err   error
		total int
		list  []*entity.Lose
		out   = &model.LoseListResponse{}
	)

	if auth.ContextOs(ctx) != "web" {
		userID, _ := auth.ContextUserID(ctx)
		in.UserId = &userID
	}

	if total, list, err = a.iLose.List(ctx, in); err != nil {
		return nil, err
	}

	out.Total = total
	out.List = model.LosesEntityToDto(list)

	return out, nil
}

// Find 列表查询
func (a *lose) Find(ctx context.Context, in *model.LoseInfoRequest) (*model.LoseInfo, error) {
	var (
		err  error
		data *entity.Lose
		out  = &model.LoseInfo{}
	)

	if data, err = a.iLose.Find(ctx, in); err != nil {
		return nil, err
	}

	out = model.LoseEntityToDto(data)
	return out, nil
}

// buildLose 构建创建数据现场
func buildLose(in *model.LoseCreateRequest) *entity.Lose {
	// todo: check the entity is required
	return &entity.Lose{

		EbikeId: in.EbikeId,

		UserId: in.UserId,

		Addr: in.Addr,

		LoseTime: in.LoseTime,

		Status: in.Status,

		LockStatus: in.LockStatus,

		Result: in.Result,

		SolverId: in.SolverId,

		Desc: in.Desc,

		LoseType:    in.LoseType,
		EbikeName:   in.EbikeName,
		EbikeImage:  in.EbikeImage,
		BatteryNo:   in.BatteryNo,
		EbikeTypeId: in.EbikeTypeId,

		CreatedAt: time.Now().Unix(),

		UpdatedAt: time.Now().Unix(),
	}
}
